/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
 *
 */

import { formatTime, Module } from '@ohos/hvigor';

import { CodeType } from '../enum/code-type-enum.js';
import { AbstractModulePlugin } from '../plugin/common/abstract-module-plugin.js';
import { BuildNativeWithCmake } from '../tasks/build-native-with-cmake.js';
import { BuildNativeWithNinja } from '../tasks/build-native-with-ninja.js';
import { CacheNativeLibs } from '../tasks/cache-native-libs.js';
import { TaskNames } from '../tasks/common/task-names.js';
import { ConfigureCmake } from '../tasks/configure-cmake.js';
import { DoNativeStrip } from '../tasks/do-native-strip.js';
import { GeneratePkgModuleJson } from '../tasks/generate-pkg-module-json';
import { ArkLinter } from '../tasks/har/ark-linter.js';
import { AbstractModuleHookTask } from '../tasks/hook/abstract-module-hook-task.js';
import { AssembleHap } from '../tasks/hook/assemble/assemble-hap.js';
import { AssembleHar } from '../tasks/hook/assemble/assemble-har.js';
import { CompileNativeHook } from '../tasks/hook/native/compile-native-hook.js';
import { BuildHarPreviewerRes } from '../tasks/hook/previewer/build-har-previewer-res.js';
import { BuildPreviewerRes } from '../tasks/hook/previewer/build-previewer-res.js';
import { PreviewBuild } from '../tasks/hook/previewer/preview-build.js';
import { LegacyPackageHar } from '../tasks/legacy-tasks/har/legacy-package-har.js';
import { LegacyProcessHarArtifacts } from '../tasks/legacy-tasks/har/legacy-process-har-artifacts.js';
import { LegacyProcessOHPackageJson } from '../tasks/legacy-tasks/har/legacy-process-oh-package-json.js';
import { LegacyHookCompileResource } from '../tasks/legacy-tasks/hook/legacy-hook-compile-resource.js';
import { LegacyArkCompile } from '../tasks/legacy-tasks/legacy-ark-compile.js';
import { LegacyCompileLiteNode } from '../tasks/legacy-tasks/legacy-compile-lite-node.js';
import { LegacyCompileNode } from '../tasks/legacy-tasks/legacy-compile-node.js';
import { LegacyGenLiteSource } from '../tasks/legacy-tasks/legacy-gen-lite-source.js';
import { LegacyGenerateHarJsManifest } from '../tasks/legacy-tasks/legacy-generate-har-js-manifest.js';
import { LegacyGenerateHarLoaderJson } from '../tasks/legacy-tasks/legacy-generate-har-loader-json.js';
import { LegacyGenerateJsManifest } from '../tasks/legacy-tasks/legacy-generate-js-manifest.js';
import { LegacyGenerateLoaderJson } from '../tasks/legacy-tasks/legacy-generate-loader-json.js';
import { LegacyGenerateMetadata } from '../tasks/legacy-tasks/legacy-generate-metadata.js';
import { LegacyMakePackInfo } from '../tasks/legacy-tasks/legacy-make-pack-info.js';
import { LegacyMergeProfile } from '../tasks/legacy-tasks/legacy-merge-profile.js';
import { LegacyOhosTestArkCompile } from '../tasks/legacy-tasks/legacy-ohos-test-ark-compile.js';
import { LegacyOhosTestCompileNode } from '../tasks/legacy-tasks/legacy-ohos-test-compile-node.js';
import { LegacyPackageHap } from '../tasks/legacy-tasks/legacy-package-hap.js';
import { LegacyPreBuild } from '../tasks/legacy-tasks/legacy-pre-build.js';
import { LegacyPreviewerArkCompile } from '../tasks/legacy-tasks/legacy-previewer-ark-compile.js';
import { LegacyProcessProfile } from '../tasks/legacy-tasks/legacy-process-profile.js';
import { LegacySignLiteBin } from '../tasks/legacy-tasks/legacy-sign-lite-bin.js';
import { LegacySyscapTransform } from '../tasks/legacy-tasks/legacy-syscap-transform.js';
import { MergeNodeAssets } from '../tasks/legacy-tasks/merge-node-assets.js';
import { PreCheckSyscap } from '../tasks/pre-check-syscap.js';
import { ProcessLibs } from '../tasks/process-libs.js';
import { ModuleTaskService } from '../tasks/service/module-task-service.js';
import { TargetTaskService } from '../tasks/service/target-task-service.js';
import { SignHap } from '../tasks/sign-hap.js';
import { SyscapTransform } from '../tasks/syscap-transform.js';
import { BuildUnitTestHook } from '../tasks/unitTest/build-unit-test-hook.js';
import { LegacyUnitTestArkCompile } from '../tasks/legacy-tasks/unit-test/legacy-unit-test-ark-compile.js';
import { UnitTestBuild } from '../tasks/unitTest/unit-test-build.js';
import { ValidateSigning } from '../tasks/validate-sign.js';
import { OhosLogger } from './log/ohos-logger.js';
import { dynamicResolveResourceTasks } from './task-util.js';

const log = OhosLogger.getLogger('TaskInitialization');

export const legacyHapTasksInitialize = (plugin: AbstractModulePlugin) => {
  const start: [number, number] = process.hrtime();
  const module: Module | undefined = plugin.getModuleModel()?.getModule();
  if (!module) {
    log.printErrorExit('INVALID_MODULE_MODEL');
    return;
  }
  const moduleTaskService: ModuleTaskService | undefined = plugin.getTaskService();
  if (!moduleTaskService) {
    log.printErrorExit('INVALID_MODULE_MODEL');
    return;
  }
  const tasks: AbstractModuleHookTask[] = [];
  tasks.push(new AssembleHap(moduleTaskService, true));
  tasks.push(new BuildPreviewerRes(moduleTaskService, true));
  tasks.push(...legacyCommonHooksInitialize(moduleTaskService));
  initializeTargetsTasks(module, plugin.getNeedExecTargetServiceList(), tasks);
  log.debug(`Module ${module.getName()} task initialization takes ${formatTime(process.hrtime(start))}`);
};

export const legacyHarTasksInitialize = (plugin: AbstractModulePlugin) => {
  const start: [number, number] = process.hrtime();
  const moduleTaskService: ModuleTaskService | undefined = plugin.getTaskService();
  if (!moduleTaskService) {
    log.printErrorExit('INVALID_MODULE_MODEL');
    return;
  }
  const module: Module | undefined = plugin.getModuleModel()?.getModule();
  if (!module) {
    log.printErrorExit('INVALID_MODULE_MODEL');
    return;
  }
  const tasks: AbstractModuleHookTask[] = [];
  tasks.push(new AssembleHar(moduleTaskService, true));
  tasks.push(new BuildHarPreviewerRes(moduleTaskService, true));
  tasks.push(...legacyCommonHooksInitialize(moduleTaskService));
  initializeTargetsTasks(module, plugin.getNeedExecTargetServiceList(), tasks);
  log.debug(`Module ${module.getName()} task initialization takes ${formatTime(process.hrtime(start))}`);
};

export const legacyCommonHooksInitialize = (moduleTaskService: ModuleTaskService) => {
  const tasks: AbstractModuleHookTask[] = [];
  tasks.push(new CompileNativeHook(moduleTaskService));
  tasks.push(new PreviewBuild(moduleTaskService, true));
  tasks.push(new UnitTestBuild(moduleTaskService, true));
  return tasks;
};

const initializeTargetsTasks = (module: Module, targets: TargetTaskService[], tasks: AbstractModuleHookTask[]) => {
  targets.forEach((target) => {
    tasks.forEach((task) => module.registry(task) && task.initTaskDepends(target));
    legacyTasksInitialize(module, target);
  });
};

export const legacyTasksInitialize = (module: Module, service: TargetTaskService) => {
  module.registry(new LegacyPreBuild(service));
  module.registry(new LegacyMergeProfile(service));
  module.registry(new LegacyGenerateJsManifest(service));
  module.registry(new LegacyGenerateLoaderJson(service));
  module.registry(new LegacyMakePackInfo(service));
  module.registry(new LegacyProcessOHPackageJson(service));
  module.registry(new LegacyProcessProfile(service));
  dynamicResolveResourceTasks(service, module);
  module.registry(new LegacyHookCompileResource(service));
  module.registry(new LegacyGenerateHarLoaderJson(service));
  module.registry(new LegacyGenerateHarJsManifest(service));
  module.registry(new LegacyPackageHap(service));
  module.registry(new LegacyProcessHarArtifacts(service));
  module.registry(new LegacyPackageHar(service));
  module.registry(new LegacyGenLiteSource(service));
  module.registry(new MergeNodeAssets(service));
  module.registry(new LegacyCompileLiteNode(service));
  module.registry(new BuildUnitTestHook(service, true));
  module.registry(new LegacyGenerateMetadata(service));
  module.registry(new LegacySyscapTransform(service));

  module.registry(new LegacySignLiteBin(service));
  module.registry(new ValidateSigning(service));
  module.registry(new LegacyArkCompile(service, CodeType.ETS, TaskNames.LegacyFATask.COMPILE_ARK));
  module.registry(new LegacyCompileNode(service, CodeType.ETS, TaskNames.LegacyFATask.COMPILE_NODE));
  module.registry(new LegacyArkCompile(service, CodeType.JS, TaskNames.LegacyFATask.COMPILE_ARK));
  module.registry(new LegacyCompileNode(service, CodeType.JS, TaskNames.LegacyFATask.COMPILE_NODE));
  module.registry(new LegacyOhosTestArkCompile(service, CodeType.ETS));
  module.registry(new LegacyOhosTestArkCompile(service, CodeType.JS));
  module.registry(new LegacyOhosTestCompileNode(service, CodeType.ETS));
  module.registry(new LegacyOhosTestCompileNode(service, CodeType.JS));
  module.registry(new LegacyPreviewerArkCompile(service, CodeType.ETS, { name: 'LegacyPreviewCompile' }));
  module.registry(new LegacyPreviewerArkCompile(service, CodeType.JS, { name: 'LegacyPreviewCompile' }));
  module.registry(new LegacyUnitTestArkCompile(service, CodeType.ETS, { name: 'LegacyUnitTest' }));
  module.registry(new LegacyUnitTestArkCompile(service, CodeType.JS, { name: 'LegacyUnitTest' }));
  module.registry(new BuildNativeWithCmake(service));
  module.registry(new BuildNativeWithNinja(service));
  module.registry(new ConfigureCmake(service));
  module.registry(new ProcessLibs(service));
  module.registry(new DoNativeStrip(service));
  module.registry(new CacheNativeLibs(service));
  module.registry(new SignHap(service));
  module.registry(new PreCheckSyscap(service, TaskNames.CommonTask.PRE_CHECK_SYSCAP));
  module.registry(new SyscapTransform(service));
  module.registry(new ArkLinter(service));
  module.registry(new GeneratePkgModuleJson(service));
};
